#!/bin/bash

#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

#
# Copyright 2020 Joyent, Inc.
#

#
# This script allows starting Jenkins builds from the command-line. To
# use this, you will need to get an API token for a Jenkins user, and
# provide it to the script through the JENKINS_AUTH environment variable
# or the -u option, in the form <user>:<api token>.
#

if [[ -n "$TRACE" ]]; then
	export PS4='[\D{%FT%TZ}] ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
	set -o xtrace
fi
set -o errexit
set -o pipefail

PROGNAME=$0

function usage() {
	if [[ -n $1 ]]; then
		printf "%s: %s\n" "$PROGNAME" "$1" >&2
	fi
	printf "usage:\n    $PROGNAME [-v] [-H url] [-b BRANCH] [-F PLAT_FLAVOR] [-u auth] <-g GITREPO> project\n" >&2
	exit 2
}

while getopts 'F:H:u:b:hvg:' opt; do
	case $opt in
	H) JENKINS_URL=$OPTARG;;
	u) JENKINS_AUTH=$OPTARG;;
	b) BRANCH=$OPTARG;;
	g) GITREPO=$OPTARG;;
	v) VERBOSE=true;;
	F) PLAT_FLAVOR=$OPTARG;;
	h) usage;;
	:) usage "-$OPTARG requires an argument";;
	\?) usage "illegal option: -$OPTARG";;
	esac
done

PROJECT=${@:$OPTIND:1}

if [[ -n "$PLAT_FLAVOR" ]]; then
	case $PROJECT in
		"platform")
			case "$PLAT_FLAVOR" in
				"triton"|"smartos"|"triton-and-smartos")
					;;
				*)
					echo "ERROR: unknown platform flavor, expecting one of:"
					echo "    smartos"
					echo "    triton"
					echo "    triton-and-smartos"
					exit 1
					;;
			esac
		;;
	*)
		usage "-F should only be used for platform builds"
		;;
	esac
fi

if [[ -z $PROJECT ]]; then
	usage "project to build must be specified"
fi

if [[ -z $JENKINS_URL ]]; then
	JENKINS_URL=https://jenkins.joyent.us
fi

if [[ -z $JENKINS_AUTH ]]; then
	usage "JENKINS_AUTH must be set to <user>:<api token> (get it here: ${JENKINS_URL}/me/configure)"
fi

if [[ -z $GITREPO ]]; then
	usage "-g GITREPO must be specified"
fi

BUILD_URL="$JENKINS_URL/job/joyent-org/job/$GITREPO/job/$BRANCH/build"

case $PROJECT in
	"platform")
		if [[ -n "$PLAT_FLAVOR" ]]; then
			BUILD_PARAM="$(printf '{"name": "PLATFORM_BUILD_FLAVOR", "value": "%s"}' "${PLAT_FLAVOR}")"
			BUILD_PARAM="${BUILD_PARAM},{\"name\": \"ONLY_BUILD_STRAP_CACHE\", \"value\": \"false\"}"
		fi
		;;
	"headnode")
		if [[ -n "$BRANCH" ]]; then
			BUILD_PARAM="$(printf '{"name": "CONFIGURE_BRANCHES", "value": "bits-branch: %s"}' "${BRANCH}")"
			BUILD_PARAM="${BUILD_PARAM},{\"name\": \"INCLUDE_DEBUG_STAGE\", \"value\": \"true\"}"
		fi
		;;
esac

if [[ -n $VERBOSE ]]; then
	CURL_OPTS=(-i)
else
	CURL_OPTS=(-s)
fi

if [[ -n "$BUILD_PARAM" ]]; then
	JENKINS_JOB_JSON="{\"parameter\":[$BUILD_PARAM]}"
else
	# When posting, even if we have no parameters, we still need some data,
	# otherwise Jenkins will complain.
	JENKINS_JOB_JSON="{\"parameter\":[]}"
fi

CRUMB_URL="$JENKINS_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,\":\",//crumb)"

# Fetch the CSRF token to send in our request's headers
CRUMB=$(curl ${CURL_OPTS[@]} --user "$JENKINS_AUTH" "$CRUMB_URL")


curl ${CURL_OPTS[@]} -X POST -H "$CRUMB" "$BUILD_URL" --user "$JENKINS_AUTH" \
    --data-urlencode json="${JENKINS_JOB_JSON}"
